import gym
from gym import envs
import numpy as np
from gym.spaces import Box, Discrete, Dict, Tuple, MultiBinary, MultiDiscrete

'''观测空间定义'''
'''
Box 用于连续值空间。描述 n 维连续空间。这是一个有界空间，我们可以在其中定义上限和下限，这些上限和下限描述了我们的观察可以采用的有效值。
Discrete 用于单个离散值空间， 描述一个离散空间，其中 {0， 1， ...， n-1} 是我们的观察或操作可以采用的可能值。。
Dict 和 Tuple 用于组合多个子空间，键值对和数组。
MultiBinary 用于多维二元空间。创建 n 维二元空间。参数 n 可以是数字或数字
MultiDiscrete 用于多维离散空间。由一系列操作空间组成，每个元素中的操作数量不同。
这些空间在 Gym 中被广泛用于定义强化学习问题的 状态空间 和 动作空间，提供了强大的灵活性来描述不同的任务环境。
'''

# Box：
# low=-1.0: 每个维度的最小值是 -1.0。
# high=2.0: 每个维度的最大值是 2.0。
# shape=(3,): 空间是三维的，每个维度都有独立的取值范围。
# dtype=np.float32: 数据类型为 32 位浮点数。
observation_space = Box(low=-1.0, high=2.0, shape=(3,), dtype=np.float32)
# sample() 方法会从定义的空间中随机采样，生成一个合法的观测值
print('observation_space:', observation_space.sample())
# Discrete 是一个离散空间，用于表示有限个整数值的状态或动作。
# Discrete(4): 表示空间包含的整数值为 [0, 1, 2, 3]，总共有 4 个可能值。
observation_space = Discrete(4)
print('observation_space:', observation_space.sample())
# 这是 Discrete 空间的扩展形式，支持自定义起始值：
# Discrete(5, start=-2) 表示空间包含的整数值为 [-2, -1, 0, 1, 2]，共 5 个值。
observation_space = Discrete(5, start=-2)
observation_space.sample()
# dict 是一个字典空间，用于表示多个变量的组合，每个变量都有自己的空间。
# {"position": Discrete(2), "velocity": Discrete(3)}: 这是一个字典：
# position: 一个取值范围为 [0, 1] 的离散空间。
# velocity: 一个取值范围为 [0, 1, 2] 的离散空间。
# 输出: OrderedDict([('position', 0), ('velocity', 1)])
observation_space = Dict({"position": Discrete(2), "velocity": Discrete(3)})
observation_space.sample()
# Tuple 是一个元组空间，用于表示多个变量的组合，每个变量都有自己的空间。
# (Discrete(2), Discrete(3)): 这是一个元组：
# 第一个元素是 [0, 1] 的离散空间。
# 第二个元素是 [0, 1, 2] 的离散空间。
# 输出: (1, 2)
observation_space = Tuple((Discrete(2), Discrete(3)))
observation_space.sample()
# MultiBinary 是一个多元二值空间，用于表示固定数量的二元变量（每个变量只能是 0 或 1）。
# MultiBinary(5): 表示包含 5 个二元变量。
# sample() 方法会随机生成一个长度为 5 的数组，其中每个值是 0 或 1。例如，输出 [1, 1, 1, 0, 1]。
# 输出: [1 1 1 0 1]
observation_space = MultiBinary(5)
observation_space.sample()
# MultiDiscrete 是一个多维离散空间，用于表示多个离散变量，每个变量有不同的取值范围。
# MultiDiscrete([5, 2, 2]):
# 第一个变量的取值范围为 [0, 1, 2, 3, 4]（5 个值）。
# 第二个变量的取值范围为 [0, 1]（2 个值）。
# 第三个变量的取值范围为 [0, 1]（2 个值）。
# 输出: [3 0 0]
observation_space = MultiDiscrete([5, 2, 2])
observation_space.sample()
